<template>
  <div style="display: flex; height: 100%">
    <el-container>
      <div style="width: 300px; border-right: 1px solid #ccc; padding: 10px">
        <el-select
          v-model="searchForm.appCode"
          placeholder="应用"
          @change="onSearch"
        >
          <el-option
            v-for="item in menusApp"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          ></el-option>
        </el-select>
        <el-tree
          class="cus-tree"
          :data="menuTree"
          :props="defaultProps"
          default-expand-all
          node-key="id"
          @node-click="handleNodeClick"
        >
          <template #default="{ node, data }">
            <span class="custom-tree-node">
              <span>{{ node.label }}</span>
              <span class="tree-node-operations">
                <el-icon class="operation-icon" @click.stop="onAddMenu(data)"
                  ><Plus
                /></el-icon>
                <el-icon class="operation-icon" @click.stop="onEditMenu(data)"
                  ><Edit />
                </el-icon>
                <el-icon class="operation-icon" @click.stop="onDeleteMenu(data)"
                  ><Delete
                /></el-icon>
              </span>
            </span>
          </template>
        </el-tree>
      </div>
      <div style="flex: 1; padding: 10px">
        <el-text class="cus-title">{{ selectedMenu ? selectedMenu.description: "" }}</el-text>
        <el-divider direction="vertical"></el-divider>
        <el-button type="primary" @click="onAddPermission" icon="CirclePlus"
          >新增权限</el-button
        >
        <el-table :data="selectedMenuPermissions" style="width: 100%">
          <el-table-column prop="id" label="ID" v-if="false"></el-table-column>
          <el-table-column prop="name" label="权限名称"></el-table-column>
          <el-table-column prop="path" label="路径"></el-table-column>
          <el-table-column prop="operation" label="方法"></el-table-column>
          <el-table-column label="操作">
            <template #default="scope">
              <el-button
                link
                type="primary"
                @click="onEditPermission(scope.row)"
                >编辑</el-button
              >
              <el-button link type="primary" @click="onDeletePermission(scope.row)"
                >删除</el-button
              >
            </template>
          </el-table-column>
        </el-table>
      </div>
    </el-container>
  </div>
  <el-dialog
    v-model="dialogMenuVisible"
    :title="isEditMenu ? '修改菜单' : '新增菜单'"
    width="30%"
    header-class="dialog-custom-header"
  >
  <el-divider direction="horizontal" style="width: 95%"></el-divider>

    <el-form :model="newMenuForm" label-width="70px">
      <el-form-item label="应用编码" v-if="false">
        <el-input v-model="newMenuForm.appCode"></el-input>
      </el-form-item>
      <el-form-item label="菜单名称">
        <el-input v-model="newMenuForm.name"></el-input>
      </el-form-item>
      <el-form-item label="菜单类型">
        <el-select
          v-model="newMenuForm.type"
          placeholder="菜单类型"
          :disabled="isEditMenu"
        >
          <el-option
            v-for="item in menuTypes"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="菜单描述">
        <el-input v-model="newMenuForm.description"></el-input>
      </el-form-item>
      <el-form-item label="路径">
        <el-input v-model="newMenuForm.path"></el-input>
      </el-form-item>
      <el-form-item label="排序">
        <el-input v-model="newMenuForm.sort"></el-input>
      </el-form-item>
      <el-form-item label="父菜单ID" v-if="false">
        <el-input v-model="newMenuForm.parentId"></el-input>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogMenuVisible = false">取消</el-button>
        <el-button type="primary" @click="onSubmitMenu">确定</el-button>
      </span>
    </template>
  </el-dialog>
  <el-dialog
    v-model="dialogPermissionVisible"
    :title="isEditPermission ? '修改权限' : '新增权限'"
    width="30%"
    header-class="dialog-custom-header"
  >
  <el-divider direction="horizontal" style="width: 95%"></el-divider>
    <el-form :model="newPermissionForm" label-width="70px">
      <el-form-item label="权限名称">
        <el-input v-model="newPermissionForm.name"></el-input>
      </el-form-item>
      <el-form-item label="请求路径">
        <el-input v-model="newPermissionForm.path"></el-input>
      </el-form-item>
      <el-form-item label="请求方法">
        <el-select v-model="newPermissionForm.operation" placeholder="请选择">
          <el-option
            v-for="item in operationOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="菜单ID" v-if="false">
        <el-input v-model="newPermissionForm.menuId"></el-input>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogPermissionVisible = false">取消</el-button>
        <el-button type="primary" @click="onSubmitPermission">确定</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, reactive, computed, watch } from "vue";
import { ElMessage } from "element-plus";
import { get, post, put, del } from "@/utils/request";
const menusApp = ref([]);
const menuTypes = ref([]);
const dialogMenuVisible = ref(false);
const dialogPermissionVisible = ref(false);
const isEditMenu = ref(false); // 是否为修改菜单模式
const isEditPermission = ref(false); // 是否为修改权限模式
const newMenuForm = reactive({
  id: null,
  appCode: null,
  name: null,
  type: null,
  description: null,
  path: null,
  sort: null,
  parent: null,
});

const newPermissionForm = reactive({
  id: null,
  name: null,
  path: null,
  operation: null,
  menuId: null,
});

const searchForm = reactive({
  appCode: null,
});
const menuTree = ref([]);
const selectedMenu = ref(null);
const selectedMenuPermissions = ref([]);

const defaultProps = {
  children: "children",
  label: "description",
};

const operationOptions = [
  {
    label: "GET",
    value: "GET",
  },
  {
    label: "POST",
    value: "POST",
  },
  {
    label: "PUT",
    value: "PUT",
  },
  {
    label: "DELETE",
    value: "DELETE",
  },
];
const onSearch = (val) => {
  // 根据搜索条件，更新菜单树
  let params = {
    appCode: val,
  };
  get("/apm/menus", params)
    .then((res) => {
      // console.log("搜索结果:", res);
      if (res.data.code === 0) {
        menuTree.value = res.data.data.data;
        selectedMenuPermissions.value = [];
      } else if (res.data.code === 401) {
        sessionStorage.clear();
        window.location.assign("/login");
      } else {
        ElMessage.error(res.data.msg ? res.data.msg : res.data.message);
      }
    })
    .catch((e) => {
      ElMessage.error(e.message);
    });
};
const handleNodeClick = (data) => {
  selectedMenu.value = data;
  selectedMenuPermissions.value = data.permissions || [];
};

const onAddMenu = (data) => {
  isEditMenu.value = false;
  Object.keys(newMenuForm).forEach((key) => {
    newMenuForm[key] = null;
  });
  newMenuForm.parent = data.id;
  newMenuForm.path = data.path;
  newMenuForm.appCode = data.appCode;
  newMenuForm.type = menuTypes.value[1].value;
  dialogMenuVisible.value = true;
};

const onEditMenu = (data) => {
  isEditMenu.value = true;
  Object.assign(newMenuForm, data);
  dialogMenuVisible.value = true;
};

const onDeleteMenu = (data) => {
  del("/apm/menus/" + data.id)
    .then((res) => {
      // console.log("搜索结果:", res);
      if (res.data.code === 0) {
        onSearch(searchForm.appCode);
        ElMessage.success("删除成功");
      } else if (res.data.code === 401) {
        sessionStorage.clear();
        window.location.assign("/login");
      } else {
        ElMessage.error(res.data.msg ? res.data.msg : res.data.message);
      }
    })
    .catch((e) => {
      ElMessage.error(e.message);
    });
};

const onSubmitMenu = async () => {
  let succ = false;
  if (isEditMenu.value) {
    let payload = {
      name: newMenuForm.name,
      description: newMenuForm.description,
      path: newMenuForm.path,
      sort: newMenuForm.sort,
    };
    await put("/apm/menus/" + newMenuForm.id, payload)
      .then((res) => {
        if (res.data.code === 0) {
          onSearch(searchForm.appCode);
          succ = true;
          ElMessage.success("修改成功");
        } else if (res.data.code === 401) {
          sessionStorage.clear();
          window.location.assign("/login");
        } else {
          ElMessage.error(res.data.msg ? res.data.msg : res.data.message);
        }
      })
      .catch((e) => {
        ElMessage.error(e.message);
      });
  } else {
    // 新增菜单逻辑
    let payload = {
      appCode: newMenuForm.appCode,
      name: newMenuForm.name,
      type: newMenuForm.type,
      description: newMenuForm.description,
      path: newMenuForm.path,
      parent: newMenuForm.parent,
      sort: newMenuForm.sort,
    };
    await post("/apm/menus", payload)
      .then((res) => {
        if (res.data.code === 0) {
          onSearch(searchForm.appCode);
          succ = true;
          ElMessage.success("新增成功");
        } else if (res.data.code === 401) {
          sessionStorage.clear();
          window.location.assign("/login");
        } else {
          ElMessage.error(res.data.msg ? res.data.msg : res.data.message);
        }
      })
      .catch((e) => {
        ElMessage.error(e.message);
      });
  }
  if (succ) {
    dialogMenuVisible.value = false;
  }
  
};

const onAddPermission = () => {
  Object.keys(newPermissionForm).forEach((key) => {
    newPermissionForm[key] = null;
  });
  if (!selectedMenu.value) {
    ElMessage.error("请先选中菜单");
    return;
  }
  newPermissionForm.menuId = selectedMenu.value.id;
  newPermissionForm.path = "/api" + selectedMenu.value.path;
  isEditPermission.value = false;
  dialogPermissionVisible.value = true;
};

const onEditPermission = (row) => {
  isEditPermission.value = true;
  Object.assign(newPermissionForm, row);
  dialogPermissionVisible.value = true;
};
const onDeletePermission = (row) => {
  del("/apm/permissions/" + row.id)
    .then((res) => {
      // console.log("搜索结果:", res);
      if (res.data.code === 0) {
        // onSearch(searchForm.appCode);
        // appList.value = appList.value.filter((item) => item.id !== row.id);
        selectedMenu.value.permissions = selectedMenu.value.permissions.filter(
          (permission) => permission.id !== row.id
        );
        selectedMenuPermissions.value = selectedMenu.value.permissions;
        ElMessage.success("删除成功");
      } else if (res.data.code === 401) {
        sessionStorage.clear();
        window.location.assign("/login");
      } else {
        ElMessage.error(res.data.msg ? res.data.msg : res.data.message);
      }
    })
    .catch((e) => {
      ElMessage.error(e.message);
    });
};

const onSubmitPermission = async () => {
  // // 新增权限逻辑
  let succ = false;
  if (isEditPermission.value) {
    let payload = {
      name: newPermissionForm.name,
      path: newPermissionForm.path,
      operation: newPermissionForm.operation,
    };
    await put("/apm/permissions/" + newPermissionForm.id, payload)
      .then((res) => {
        if (res.data.code === 0) {
          const index = selectedMenu.value.permissions.findIndex(p => p.id === newPermissionForm.id);
          if (index !== -1) {
            selectedMenu.value.permissions[index] = { ...newPermissionForm };
            selectedMenuPermissions.value = selectedMenu.value.permissions;
          }
          succ = true;
          ElMessage.success("修改成功");
        } else if (res.data.code === 401) {
          sessionStorage.clear();
          window.location.assign("/login");
        } else {
          ElMessage.error(res.data.msg ? res.data.msg : res.data.message);
        }
      })
      .catch((e) => {
        ElMessage.error(e.message);
      });
  } else {
    let payload = {
      menuId: newPermissionForm.menuId,
      name: newPermissionForm.name,
      path: newPermissionForm.path,
      operation: newPermissionForm.operation,
    };
    await post("/apm/permissions", payload)
      .then((res) => {
        if (res.data.code === 0) {
          // selectedMenu.value.permissions = selectedMenu.value.permissions || [];
          newPermissionForm.id = res.data.data.id;
          selectedMenu.value.permissions.push({
            ...newPermissionForm,
          });
          selectedMenuPermissions.value = selectedMenu.value.permissions;
          succ = true;
          ElMessage.success("新增成功");
        } else if (res.data.code === 401) {
          sessionStorage.clear();
          window.location.assign("/login");
        } else {
          ElMessage.error(res.data.msg ? res.data.msg : res.data.message);
        }
      })
      .catch((e) => {
        ElMessage.error(e.message);
      });
  }
  if (succ) {
    dialogPermissionVisible.value = false;
  }
};

onMounted(async () => {
  // 获取顶级菜单列表
  let succ = false;
  await get("/apm/menus/apps")
    .then((res) => {
      // console.log("搜索结果:", res);
      if (res.data.code === 0) {
        menusApp.value = res.data.data.data;
        searchForm.appCode = menusApp.value[0].value;
        succ = true;
      } else if (res.data.code === 401) {
        sessionStorage.clear();
        window.location.assign("/login");
      } else {
        ElMessage.error(res.data.msg ? res.data.msg : res.data.message);
      }
    })
    .catch((e) => {
      ElMessage.error(e.message);
    });
  if (!succ) {
    return;
  }
  // 获取菜单类型
  await get("/apm/menus/types")
    .then((res) => {
      // console.log("搜索结果:", res);
      if (res.data.code === 0) {
        menuTypes.value = res.data.data.data;
      } else if (res.data.code === 401) {
        sessionStorage.clear();
        window.location.assign("/login");
      } else {
        ElMessage.error(res.data.msg ? res.data.msg : res.data.message);
      }
    })
    .catch((e) => {
      ElMessage.error(e.message);
    });
  onSearch(searchForm.appCode);
});
</script>

